const methods = {
    calculateAngle: (x1: number, y1: number, x2: number, y2: number) => {
        const dx = x2 - x1;
        const dy = y2 - y1;
        // 计算角度（弧度）
        let angle = Math.atan2(dy, dx);
        // 转换为度数
        angle = angle * (180 / Math.PI);
        // 确保角度在0-360度之间
        if (angle < 0) {
            angle += 360;
        }
        return angle - 45;
    },
    nextPosition: (startX: number, startY: number, endX: number, endY: number, step: number = 1) => {
        return new Promise((resolve, reject) => {
            // 计算起点到终点的距离
            const dx = endX - startX;
            const dy = endY - startY;
            const distance = Math.sqrt(dx * dx + dy * dy);

            // 如果距离为0（起点和终点相同），则返回起点坐标
            if (distance <= step) {
                reject({
                    x: endX, y: endY
                })
            }

            // 计算单位向量（方向）
            const unitX = dx / distance;
            const unitY = dy / distance;

            // 计算下一步的坐标（使用传入的步长）
            const nextX = startX + unitX * step;
            const nextY = startY + unitY * step;

            resolve({
                x: nextX, y: nextY
            })
        })
    },
    removeElementsByIndices: (arr: [], indices: []) => {
        // 复制并降序排序要删除的下标
        const sortedIndices = [...indices].sort((a, b) => b - a);

        // 遍历排序后的下标并删除对应元素
        sortedIndices.forEach(index => {
            if (index >= 0 && index < arr.length) {
                arr.splice(index, 1);
            }
        });
    },
    /**
     * 生成指定范围内的随机数
     * @param {number} min - 最小值（包含）
     * @param {number} max - 最大值（包含）
     * @returns {number} - 生成的随机数
     */
    getRandomNumber: (min: number, max: number) => {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    },
    /**
     * 生成UUID
     * */
    getUUID: () => {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    },
    /**
     * 计算二次贝塞尔曲线路径上的点
     * @param p0 - 起始点坐标，默认值为 { x: 0, y: 0 }
     * @param p1 - 结束点坐标，默认值为 { x: 0, y: 0 }
     * @param totalSegments - 路径的总段数
     * @param index - 当前计算的点索引，必须在 0 到 totalSegments 之间
     * @param which - 'start' | 'mid' | 'end'	返回该段的起点、中点还是终点
     * @returns 返回计算出的贝塞尔曲线上的点坐标 { x, y }
     */
    attackPath: (p0: {x: number, y: number}, p1: {x: number, y: number}, totalSegments: number, index: number, which: string = 'end') => {
        // 计算椭圆中心
        const cx = (p0.x + p1.x) / 2;
        const cy = (p0.y + p1.y) / 2;

        // 半长轴和半短轴
        const a = Math.abs(p1.x - p0.x) / 2;
        const b = Math.abs(p1.y - p0.y) / 2;

        // 计算 p1 到中心的向量，用于确定椭圆起始角度偏移
        const dx = p0.x - cx;
        const dy = p0.y - cy;
        const offsetAngle = Math.atan2(dy, dx); // p1 方向相对于椭圆中心的角度（弧度）

        // 每段的角度增量
        const anglePerSegment = (2 * Math.PI) / totalSegments;

        let theta;
        if (which === 'start') {
            theta = index * anglePerSegment;
        } else if (which === 'end') {
            theta = (index + 1) * anglePerSegment;
        } else {
            theta = (index + 0.5) * anglePerSegment;
        }

        // 加上偏移角度，确保从 p1 开始画椭圆
        theta += offsetAngle;

        // 参数方程
        const x = cx + a * Math.cos(theta);
        const y = cy + b * Math.sin(theta);

        return {
            x: Number(x.toFixed(4)),
            y: Number(y.toFixed(4))
        };
    },

    attackPath2: (startX: number, startY: number, endX: number, endY: number, segmentCount: number, index: number) => {
        // 计算总线段长度（一个来回）
        const segmentLength = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
        const totalLength = segmentLength * 2; // 往返路径长度

        // 计算每段的长度
        const lengthPerSegment = totalLength / segmentCount;

        // 计算当前下标所在的总距离
        const distance = index * lengthPerSegment;

        // 确定当前位置在往返路径中的哪一段
        const cyclePosition = distance % totalLength;

        let t;
        if (cyclePosition < segmentLength) {
            // 第一段：起点到终点
            t = cyclePosition / segmentLength;
        } else {
            // 第二段：终点到起点
            t = 1 - ((cyclePosition - segmentLength) / segmentLength);
        }

        // 线性插值计算坐标
        const x = startX + t * (endX - startX);
        const y = startY + t * (endY - startY);

        return { x, y };
    },
    getRandomPointOnCircle (radius: number, quadrant: number, x: number = 0, y: number = 0) {
        // 定义要排除的象限对应的角度范围
        let excludedMinDegree: number;
        let excludedMaxDegree: number;

        switch (quadrant) {
            case 1:
                excludedMinDegree = 0;
                excludedMaxDegree = 90;
                break;
            case 2:
                excludedMinDegree = 90;
                excludedMaxDegree = 180;
                break;
            case 3:
                excludedMinDegree = 180;
                excludedMaxDegree = 270;
                break;
            case 4:
                excludedMinDegree = 270;
                excludedMaxDegree = 360;
                break;
            default:
                throw new Error("无效的象限值，请输入1, 2, 3或4");
        }

        let randomDegree: number;
        do {
            // 生成0到360度之间的随机角度
            randomDegree = Math.random() * 360;
        } while (randomDegree >= excludedMinDegree && randomDegree < excludedMaxDegree); // 确保生成的角度不在排除的象限内

        // 将角度转换为弧度
        const radians = randomDegree * (Math.PI / 180);

        // 计算圆上点的坐标（相对于原点）
        return {
            point: {
                x: x + radius * Math.cos(radians),
                y: y + radius * Math.sin(radians)
            },
            quadrant: this.getQuadrant(randomDegree), // 确定生成点所在的象限
            randomDegree: randomDegree // 返回生成的角度
        };
    },
    // 辅助函数：确定角度所属的象限
    getQuadrant(degree: number) {
        if (degree >= 0 && degree < 90) return 1;
        else if (degree >= 90 && degree < 180) return 2;
        else if (degree >= 180 && degree < 270) return 3;
        else return 4;
    },
    /**
     * 计算点的两个线段
     * @param p0 - 起始点坐标，默认值为 { x: 0, y: 0 }
     * @param p1 - 结束点坐标，默认值为 { x: 0, y: 0 }
     * */
    getStartEndPoint(p0: { x: number, y: number }, p1: { x: number, y: number }) {
        // 计算向量 p0→p1
        const dx = p1.x - p0.x;
        const dy = p1.y - p0.y;

        // 终点 = p1 + 向量(p0→p1)的反向延长线
        const endPoint = {
            x: p1.x - 2 * dx,
            y: p1.y - 2 * dy
        };

        return [p1, endPoint];
    }
}

export default methods
